package cn.tedu.csmall.all.adapter.transaction;

import cn.tedu.csmall.all.adapter.mapper.OrderMapper;
import cn.tedu.csmall.all.service.IStockService;
import cn.tedu.csmall.commons.exception.CoolSharkServiceException;
import cn.tedu.csmall.commons.pojo.order.dto.OrderAddDTO;
import cn.tedu.csmall.commons.pojo.order.entity.Order;
import cn.tedu.csmall.commons.pojo.stock.dto.StockReduceCountDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;

/**
 * @author java@tedu.cn
 * @version 1.0
 */
@Component
@RocketMQTransactionListener
public class OrderAddTransactionListener implements RocketMQLocalTransactionListener {
    @DubboReference
    private IStockService stockService;
    @Autowired
    private OrderMapper orderMapper;

    /**
     * 1.减库存
     * 1.1 减成功 进入第二步生单
     * 1.2 减失败 rollback
     * 2.生单
     * 2.1 生单成功 commit
     * 2.2 生单失败 补偿库存 unkonwn
     * 其他异常问题 unknown
     * @param message userId":"commodityCode
     * @param o OrderAddDTO
     * @return
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object o) {
        OrderAddDTO orderAddDTO=(OrderAddDTO)o;
        try{
            StockReduceCountDTO countDTO=new StockReduceCountDTO();
            countDTO.setCommodityCode(orderAddDTO.getCommodityCode());
            countDTO.setReduceCount(orderAddDTO.getCount());
            // 利用Dubbo调用stock模块减少库存的业务逻辑层方法实现功能
            stockService.reduceCommodityCount(countDTO);
        }catch (CoolSharkServiceException e){
            //返回rollback
            return RocketMQLocalTransactionState.ROLLBACK;
        }catch (Throwable e){
            //返回unknown
            return RocketMQLocalTransactionState.UNKNOWN;
        }
        try{
            Order order=new Order();
            BeanUtils.copyProperties(orderAddDTO,order);
            orderMapper.insertOrder(order);
        }catch (Exception e){
            return RocketMQLocalTransactionState.UNKNOWN;
        }
        return RocketMQLocalTransactionState.COMMIT;
    }

    /**
     * 1. 检查订单是否成功.
     * 1.1 成功 commit
     * 1.2 没有成功 进入第2步
     * 2. 库存对当前订单是否已经减成功
     * 2.1 减成功,回退 第3步
     * 2.2 没减成功 rollback
     * 3.回退库存
     * 3.1 可能失败 unknown
     * 3.2 回退成功 rollback
     * @param message
     * @return
     */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        //状态不明确,回调check方法,检查库存是否减少,检查订单是否生成
        String userIdAndCommodityCode = (String) message.getPayload();
        Object name = message.getHeaders().get("name");
        Object orderId = message.getHeaders().get("orderId");
        String userId=userIdAndCommodityCode.split(":")[0];
        String commodityCode=userIdAndCommodityCode.split(":")[1];
        OrderAddDTO orderAddDTO=new OrderAddDTO();
        orderAddDTO.setUserId(userId);
        orderAddDTO.setCommodityCode(commodityCode);
        int exist = orderMapper.selectExists(orderAddDTO);
        if (exist>0){
            //当前检查的这个订单已经生成,说明库存肯定减了
            return RocketMQLocalTransactionState.COMMIT;
        }
        //存在一个库存的日志表格,记录减库存的日志数据
        //通过传递订单信息,查询日志,如果减了就回退,如果没减,没有操作
        //返回给调用者检查结果是成功还是失败
        try{
            stockService.checkStockData();
        }catch (CoolSharkServiceException e){
            //没有库存减少的日志 没有任何减库存的操作
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        //补偿回退 TODO
        try{
            //补偿
            System.out.println("订单没有生成.库存减少了,开始补偿");
        }catch (Exception e){
            //补偿失败
            return RocketMQLocalTransactionState.UNKNOWN;
        }
        return RocketMQLocalTransactionState.ROLLBACK;
    }
}
